package com.example.demo.controller;

import com.example.demo.entity.Ingredient;
import com.example.demo.entity.Order;
import com.example.demo.entity.Taco;
import com.example.demo.entity.Type;
import com.example.demo.service.IngredientRepository;
import com.example.demo.service.TacoRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;


import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Controller
@RequestMapping("/design")
@SessionAttributes("order") //注解只用作用在 类 上，作用是将指定的 Model 的键值对保存在 session 中。可以让其他请求共用 session 中的键值对。
public class DesignTacoController {

    private final IngredientRepository ingredientRepo;

    private TacoRepository designRepo;
    ;

    @Autowired
    public DesignTacoController(IngredientRepository ingredientRepository, TacoRepository tacoRepository) {
        this.ingredientRepo = ingredientRepository;
        this.designRepo = tacoRepository;
    }

    /*
     @ModelAttribute
    注解在参数上，会将客户端传递过来的参数按名称注入到指定对象中，并且会将这个对象自动加入ModelMap中；
    注解在方法上，会在每一个@RequestMapping标注的方法前执行，如果有返回值，则自动将该返回值加入到ModelMap中
     */
    @ModelAttribute(name = "order") //确保会在模型中创建一个order对象
    public Order order() {
        return new Order();
    }

    @ModelAttribute(name = "taco")
    private Taco taco() {
        return new Taco();
    }

    @GetMapping
    public String showDesignForm(Model model) {
        List<Ingredient> ingredients = new ArrayList<>();
        ingredientRepo.findAll().forEach(i -> ingredients.add(i));
        Type[] types = Type.values();
        for (Type type :
                types) {
            model.addAttribute(type.toString().toLowerCase(),
                    filterByType(ingredients, type));
        }
//        model.addAttribute("design",new Taco());
        return "design";
    }

    private List<Ingredient> filterByType(List<Ingredient> list, Type type) {
        return list.stream().filter(x -> x.getType().equals(type)).collect(Collectors.toList());
    }

    @PostMapping
    //@Valid 会告诉SpringMVC要对提交的Taco对象进行检验，而校验时机是在他绑定完表单数据之后，调用processorDesign之前
    public String processorDesign(@Valid Taco design, Errors errors, @ModelAttribute Order order) {
        if (errors.hasErrors()) {
            return "design";
        }
        Taco saved = designRepo.save(design);
        order.addDesign(saved);
        return "redirect:/orders/current";  //redirect 前缀，重定向视图，更具体讲在方法完成后，用户浏览器会重定向到相对路径/order/current
    }

}
